import { createApp } from 'vue'
import { createPinia } from 'pinia'
import router from './router'
import App from './App.vue'

// Element Plus
import ElementPlus from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import 'element-plus/dist/index.css'

import './styles.css'
import { useAuthStore } from './stores/auth'
import { useMenuStore } from './stores/menu'

const app = createApp(App)

// default title used as fallback
const DEFAULT_TITLE = ''

async function init() {
  try {
    // attempt to fetch a public site name (no auth) and use it as document.title
    const res = await fetch('/public/site-name')
    if (res && res.ok) {
      const body = await res.json().catch(() => ({}))
      if (body && body.value) document.title = body.value
      else document.title = DEFAULT_TITLE
    } else {
      document.title = DEFAULT_TITLE
    }
  } catch (e) {
    document.title = DEFAULT_TITLE
  }

  // install Pinia and create store instances before mount so we can initialize UI state
  const pinia = createPinia()
  app.use(pinia)
  app.use(router)
  app.use(ElementPlus, { locale: zhCn })

  // Initialize menu state on startup: when user already authenticated (token in localStorage),
  // load menus and set active top and sidebar visibility based on current route so a refresh
  // preserves the current page and sidebar instead of forcing navigation to the dashboard.
  try {
    const auth = useAuthStore()
    const menu = useMenuStore()
    if (auth.isAuthenticated) {
      try {
        // ensure menus are loaded so we can compute the correct top menu for current route
        try { await auth.fetchMenus() } catch (e) { /* ignore fetch errors */ }

        const menusData: any[] = (auth as any).menus?.value || []
        const currentPath = router.currentRoute.value?.path || '/'

        // find the top-level menu name whose subtree contains currentPath
        function normalize(p: string | undefined) {
          if (!p) return ''
          try { p = decodeURI(p) } catch (e) {}
          // ensure leading slash and no trailing slash (except root)
          if (!p.startsWith('/')) p = '/' + p
          if (p.length > 1 && p.endsWith('/')) p = p.slice(0, -1)
          return p
        }

        function pathMatches(menuUrl: string | undefined, path: string): boolean {
          const mu = normalize(menuUrl)
          const p = normalize(path)
          if (!mu) return false
          if (mu === p) return true
          // allow matching when one is a suffix of the other (handles prefixed URLs)
          if (p.endsWith(mu) || mu.endsWith(p)) return true
          // allow matching on simple name segments (e.g. '/youth/screening' vs '/screening')
          const pSeg = p.split('/').filter(Boolean)
          const muSeg = mu.split('/').filter(Boolean)
          if (pSeg.length && muSeg.length && pSeg[pSeg.length-1] === muSeg[muSeg.length-1]) return true
          return false
        }

        function findTopForPath(items: any[], path: string): string | null {
          for (const item of items || []) {
            if (!item) continue
            if (pathMatches(item.url, path)) return item.name
            if (item.children && item.children.some((c: any) => pathMatches(c.url, path))) return item.name
            if (item.children && item.children.length) {
              const childRes = findTopForPath(item.children, path)
              if (childRes) return item.name
            }
          }
          return null
        }

        const topName = findTopForPath(menusData, currentPath)
        if (topName) {
          // set active top to the matching top menu and show sidebar if it has visible children
          try { menu.setActiveTop(topName) } catch (e) {}
          let topItem = menusData.find((m: any) => m.name === topName)
          // helper to determine if a node (or its descendants) contains any visible non-function child
          function hasVisibleChildren(nodes: any[] | undefined): boolean {
            if (!nodes || !Array.isArray(nodes) || nodes.length === 0) return false
            for (const n of nodes) {
              if (!n) continue
              // treat nodes with is_function === 1 as function items (not visible as menu entries)
              if (Number((n.is_function ?? n.b_function ?? n.bFunction ?? n.isFunction) || 0) !== 1) {
                return true
              }
              // otherwise check descendants
              if (n.children && n.children.length) {
                if (hasVisibleChildren(n.children)) return true
              }
            }
            return false
          }

          // if topItem exists but has no children loaded, try to fetch them so SideMenu can render
          try {
            if (topItem && (!Array.isArray(topItem.children) || topItem.children.length === 0)) {
              const rawId = topItem.id ?? null
              const pid = Number(rawId)
              if (!Number.isNaN(pid)) {
                try {
                  const fetched = await auth.fetchChildren(pid)
                  // refresh reference to menusData and topItem after fetch
                  const refreshed: any[] = (auth as any).menus?.value || []
                  topItem = refreshed.find((m: any) => m.name === topName) || topItem
                } catch (e) {
                  /* ignore fetchChildren errors */
                }
              }
            }
          } catch (e) { /* ignore */ }

          const hasChildren = topItem ? hasVisibleChildren(topItem.children) : false
          try { menu.setShowSidebar(!!hasChildren) } catch (e) {}
        } else {
          // no matching top menu for current route — keep sidebar hidden by default
          try { menu.setShowSidebar(false) } catch (e) {}
        }
      } catch (e) { /* ignore store method issues */ }
    }
  } catch (e) {
    /* ignore store initialization errors */
  }

  app.mount('#app')
}

init()
